﻿global using static Global;

using GitHubCopilotProxies.Handlers;

using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Unicode;
using System.Threading.Tasks;

static class Global
{
    public const string TextContentType = "text/plain; charset=utf-8";
    public const string HtmlContentType = "text/html; charset=utf-8";
    public const string JsonContentType = "application/json; charset=utf-8";

    public static HttpContext ResponseWithXOAuthScopes(this HttpContext httpContext)
    {
        const string scopes = "gist, read:org, repo, user, workflow, write:public_key";
        httpContext.Response.Headers["X-OAuth-Scopes"] = scopes;
        return httpContext;
    }
    public static async Task ResponseJsonAsync(this HttpContext httpContext, string jsonString)
    {
        httpContext.Response.ContentType = JsonContentType;
        await httpContext.Response.WriteAsync(jsonString, Encoding.UTF8, httpContext.RequestAborted);
        await httpContext.Response.CompleteAsync();
    }
    public static async Task ResponseJsonAsync<T>(this HttpContext httpContext, T data) where T : class
    {
        var jsonString = data.SerializeToJsonString();
        await httpContext.ResponseJsonAsync(jsonString);
    }

    public static string SerializeToJsonString<T>(this T data) where T : class
    {
        return JsonSerializer.Serialize(data, AppJsonSerializerContext.Web.Options);
    }
    public static async Task<T?> DeserializeStreamAsync<T>(this HttpContext httpContext, Stream stream) where T : class
    {
        return await JsonSerializer.DeserializeAsync<T>(stream, AppJsonSerializerContext.Web.Options, httpContext.RequestAborted);
    }
}

[JsonSerializable(typeof(string[]))]
[JsonSerializable(typeof(float[]))]
[JsonSerializable(typeof(List<string>))]
[JsonSerializable(typeof(Dictionary<string, string>))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(Telemetry.TelemetryResponse))]
[JsonSerializable(typeof(CopilotCompletions.ChunkRequest))]
[JsonSerializable(typeof(CopilotCompletions.Chunk))]
[JsonSerializable(typeof(CopilotCompletions.Chunk.RangeNode))]
[JsonSerializable(typeof(CopilotCompletions.Chunk.ChunkEmbeddingNode))]
[JsonSerializable(typeof(CopilotCompletions.ChunkResponse))]
[JsonSerializable(typeof(CopilotCompletions.EmbeddingResponse))]
[JsonSerializable(typeof(CopilotCompletions.EmbeddingResponse.OutputNode))]
[JsonSerializable(typeof(CopilotCompletions.EmbeddingResponse.EmbeddingNode[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
    public static readonly AppJsonSerializerContext Web = new AppJsonSerializerContext(new JsonSerializerOptions
    {
        //WriteIndented = true,
        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    });
}